#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include "sock.hpp"
#include <functional>

typedef std::function<std::string(std::string& package)> func_t;

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t callback)
        : _port(port)
        , _callback(callback)
    {

    }

    void init()
    {
        _listen_sock.Socket();
        _listen_sock.Bind(_port);
        _listen_sock.Listen();
    }

    void start()
    {
        signal(SIGCHLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);

        while(1)
        {
            std::string client_ip;
            uint16_t client_port;
            int sockfd = _listen_sock.Accept(client_ip, client_port);
            if(sockfd < 0)
                continue;
            lg(Info, "accept a new link, sockfd: %d, clientip: %s, clientport: %d", sockfd, client_ip.c_str(), client_port);
            // 提供服务
            if(fork() == 0)
            {
                // child
                _listen_sock.Close();

                // 数据计算
                char buffer[128];
                std::string stream_buffer;
                while(1)
                {

                    int n = read(sockfd, buffer, sizeof(buffer));
                    if(n > 0)
                    {
                        buffer[n] = '\0';
                        stream_buffer += buffer;
                        std::cout << stream_buffer << std::endl;
                        // std::string content = _callback(stream_buffer);
                        // if(content.empty())
                        // {
                        //     continue;
                        // }

                        while (true)
                        {
                            std::string content = _callback(stream_buffer);
                            if (content.empty())
                                break;
                            lg(Debug, "debug, response:\n%s", content.c_str());
                            lg(Debug, "debug:\n%s", stream_buffer.c_str());
                            write(sockfd, content.c_str(), content.size());
                        }

                        //write(sockfd, content.c_str(), content.size());
                    }
                    else
                    {
                        std::cout << "read err" << std::endl;
                        break;
                    }
                }
                

                exit(0);
            }
            close(sockfd);
        }
    }

    ~TcpServer()
    {

    }


private:
    Sock _listen_sock;
    uint16_t _port;
    func_t _callback;
};